package com.ruantong.dingtalk.ding.callback.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dingtalk.oapi.lib.aes.DingTalkEncryptor;
import com.ruantong.dingtalk.ding.callback.enums.AttendanceEventEnum;
import com.ruantong.dingtalk.ding.callback.listener.event.AttendanceEvent;
import com.ruantong.dingtalk.ding.callback.service.EventService;
import com.ruantong.dingtalk.ding.constant.CallbackConstant;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * @description:提供给钉钉的回调接口
 * @author: jh.chen
 * @time: 2020/11/14 20:24
 */
@RestController
@RequestMapping("/")
@Slf4j
public class CallbackController {

    /**
     * 创建应用，验证回调URL创建有效事件
     */
    private static final String EVENT_URL = "check_url";

    @Autowired
    private EventService eventService;

    @PostMapping(value = "dingCallback")
    public Object dingCallback(
            @RequestParam(value = "signature") String signature,
            @RequestParam(value = "timestamp") Long timestamp,
            @RequestParam(value = "nonce") String nonce,
            @RequestBody(required = false) JSONObject body) {
        String params = "signature:" + signature + " timestamp:" + timestamp + " nonce:" + nonce + " body:" + body;
        try {
            log.info("ding callback:" + params);
            DingTalkEncryptor dingTalkEncryptor = new DingTalkEncryptor(CallbackConstant.CALL_TOKEN, CallbackConstant.AES_KEY, CallbackConstant.SUITE_KEY);
            // 从post请求的body中获取回调信息的加密数据进行解密处理
            String encrypt = body.getString("encrypt");
            String plainText = dingTalkEncryptor.getDecryptMsg(signature, timestamp.toString(), nonce, encrypt);
            JSONObject callBackContent = JSON.parseObject(plainText);

            // 根据回调事件类型做不同的业务处理
            String eventType = callBackContent.getString("EventType");
            if (EVENT_URL.equals(eventType)) {
                log.info("验证新创建的回调URL有效性: " + plainText);
            } else if (AttendanceEventEnum.ATTENDANCE_CHECK_RECORD.value().equals(eventType)) {
                //TODO
                eventService.productCallbackEvent(new AttendanceEvent(this, AttendanceEventEnum.ATTENDANCE_CHECK_RECORD));
            }
            // 返回success的加密信息表示回调处理成功
            return dingTalkEncryptor.getEncryptedMap("success", timestamp, nonce);
        } catch (Exception e) {
            log.error("process callback fail." + params, e);
        }
        return "fail";
    }
}
